package com.zzg.mybatis.generator.controller;

import com.zzg.mybatis.generator.model.BladeCode;
import com.zzg.mybatis.generator.model.BladeModel;
import com.zzg.mybatis.generator.model.DatabaseConfig;
import com.zzg.mybatis.generator.model.DbType;
import com.zzg.mybatis.generator.model.GeneratorConfig;
import com.zzg.mybatis.generator.model.UITableColumnVO;
import com.zzg.mybatis.generator.util.DbUtil;
import com.zzg.mybatis.generator.view.AlertUtil;
import com.zzg.mybatis.generator.view.UIProgressCallback;
import java.awt.Desktop;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.sql.SQLRecoverableException;
import java.util.List;
import java.util.ResourceBundle;
import org.springblade.core.tool.utils.Func;
import org.springblade.develop.support.BladeCodeGenerator;

/**
 * bladex代码生成器
 */
public class BladexCodeController extends BaseFXController {

    private static final Logger _LOG = LoggerFactory.getLogger(BladexCodeController.class);


    @FXML
    private GridPane gridPane;

    @FXML
    private ChoiceBox<?> modelId;

    @FXML
    private TextField codeName;

    @FXML
    private TextField serviceName;

    @FXML
    private TextField tableName;

    @FXML
    private TextField tablePrefix;

    @FXML
    private TextField pkName;

    @FXML
    private TextField packageName;

    @FXML
    private ChoiceBox<?> templateType;

    @FXML
    private TextField webPath;

    @FXML
    private TextField apiPath;

    @FXML
    private ToggleGroup group1;

    @FXML
    private RadioButton baseMode1;

    @FXML
    private RadioButton baseMode2;

    @FXML
    private ToggleGroup group2;

    @FXML
    private RadioButton wrapMode1;

    @FXML
    private RadioButton wrapMode2;

    @FXML
    private ToggleGroup group3;

    @FXML
    private RadioButton feignMode1;

    @FXML
    private RadioButton feignMode2;

    @FXML
    private ToggleGroup group4;

    @FXML
    private RadioButton codeStyle1;

    @FXML
    private RadioButton codeStyle2;

    @FXML
    private TextField author;

    private DatabaseConfig selectedDatabaseConfig;
    private BladeModel bladeModel;
    private BladeCode bladeCode;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        _LOG.info("initialize");
    }

    @FXML
    public void generateCode() {
        if (StringUtils.isBlank(codeName.getText())) {
            AlertUtil.showWarnAlert("模块名不能为空");
            return;
        }
        UIProgressCallback alert = new UIProgressCallback(Alert.AlertType.INFORMATION);
        alert.show();
        try {
            BladeCodeGenerator generator = new BladeCodeGenerator();
            // 设置数据源
            generator.setDriverName(DbType.valueOf(selectedDatabaseConfig.getDbType()).getDriverClass());
            generator.setUrl(DbUtil.getConnectionUrlWithSchema(selectedDatabaseConfig));
            generator.setUsername(selectedDatabaseConfig.getUsername());
            generator.setPassword(selectedDatabaseConfig.getPassword());
            // 设置基础配置
            generator.setSystemName(((RadioButton)group4.getSelectedToggle()).getText());
            generator.setCodeName(codeName.getText());
            generator.setServiceName(serviceName.getText());
            generator.setPackageName(packageName.getText());
            generator.setPackageDir(apiPath.getText());
            generator.setPackageWebDir(webPath.getText());
            generator.setTablePrefix(Func.toStrArray(tablePrefix.getText()));
            generator.setIncludeTables(Func.toStrArray(tableName.getText()));
            // 设置是否继承基础业务字段
            generator.setHasSuperEntity(((RadioButton)group1.getSelectedToggle()).getText().equals("是"));
            // 设置是否开启包装器模式
            generator.setHasWrapper(((RadioButton)group2.getSelectedToggle()).getText().equals("是"));
            generator.run();
            alert.done();
        } catch (Exception e) {
            _LOG.error(e.getMessage(), e);
            alert.close();
            AlertUtil.showErrorAlert(e.getMessage());
        }
    }

    @FXML
    public void openTargetFolder() {
        String projectFolder = apiPath.getText();
        try {
            Desktop.getDesktop().browse(new File(projectFolder).toURI());
        }catch (Exception e) {
            AlertUtil.showErrorAlert("打开目录失败，请检查目录是否填写正确" + e.getMessage());
        }
    }

    @FXML
    public void saveGeneratorConfig() {

    }

    public void setConfig(DatabaseConfig selectedConfig) {
        if (StringUtils.isNoneBlank(
                selectedConfig.getHost(),
                selectedConfig.getPort())) {
            _LOG.info("setConfig： {} {}", selectedConfig.getHost(), selectedConfig.getPort());
            this.selectedDatabaseConfig = selectedConfig;
        }
    }

    public void setBladeModels(List list){
    }

    public void setBladeCodes(List<BladeCode> list){
        _LOG.info("setBladeCodes： {} {}");
        if(list.isEmpty()){
            return;
        }
        BladeCode bc = list.get(0);
        this.bladeCode = bc;
        codeName.setText(bc.getCodeName());
        serviceName.setText(bc.getServiceName());
        tableName.setText(bc.getTableName());
        tablePrefix.setText(bc.getTablePrefix());
        pkName.setText(bc.getPkName());
        packageName.setText(bc.getPackageName());
        author.setText(bc.getAuthor());
        apiPath.setText(bc.getApiPath());
        webPath.setText(bc.getWebPath());
        templateType.getSelectionModel().selectFirst();
        baseMode1.setSelected(bc.getBaseMode() == 2 ? true : false);
        wrapMode1.setSelected(bc.getWrapMode() == 2 ? true : false);
        feignMode2.setSelected(bc.getFeignMode() == 1 ? true : false);
        codeStyle1.setSelected(bc.getCodeStyle().equals("saber") ? true : false);
    }

    private void displayModel(TreeItem<String> treeItem) {
        if(treeItem == null) {
            return ;
        }
        DatabaseConfig selectedConfig = (DatabaseConfig) treeItem.getGraphic().getUserData();
        try {
            String filter = "blade_model";
            List<String> tables = DbUtil.getTableNames(selectedConfig, filter);
            if (tables.size() > 0) {
                ObservableList<TreeItem<String>> children = treeItem.getChildren();
                children.clear();
                for (String tableName : tables) {
                    TreeItem<String> newTreeItem = new TreeItem<>();
                    ImageView imageView = new ImageView("icons/table.png");
                    imageView.setFitHeight(16);
                    imageView.setFitWidth(16);
                    newTreeItem.setGraphic(imageView);
                    newTreeItem.setValue(tableName);
                    children.add(newTreeItem);
                }
            }else if (StringUtils.isNotBlank(filter)){
                treeItem.getChildren().clear();
            }
        } catch (SQLRecoverableException e) {
            _LOG.error(e.getMessage(), e);
            AlertUtil.showErrorAlert("连接超时");
        } catch (Exception e) {
            _LOG.error(e.getMessage(), e);
            AlertUtil.showErrorAlert(e.getMessage());
        }
    }
}

